Skip to main content

Extract filename and extension from path - 2

Here's a comprehensive solution

#!/bin/bash

# Function to extract file name and extension
extract_file_info() {
local filepath="$1"

# Check if the path ends with a slash, remove it if present
if [[ "$filepath" == */ ]]; then
filepath="${filepath%/}"
fi

# Get the base name from the full path using basename
local base_name=$(basename -- "$filepath")

# Initialize variables for file name and extension
local file_name=""
local extension=""

# Check if there is a dot in the base name (indicating an extension)
if [[ "$base_name" == */* ]]; then
# Handle paths that end with a slash or are directories
echo "File name: $base_name"
echo "Extension: (directory)"
elif [[ "$base_name" != *.* ]]; then
# No dots in the file name, no extension
file_name="$base_name"
extension=""
else
# Get the extension by splitting at the last dot
extension="${base_name##*.}"
file_name="${base_name%.*}"
fi

echo "File name: $file_name"
echo "Extension: $extension"
}

# Test cases
extract_file_info "/home/user/file.txt"
extract_file_info "./documents/report.pdf"
extract_file_info "images/photo.jpg"
extract_file_info "data.v1.2.tar.gz"
extract_file_info "README"
extract_file_info "script"
extract_file_info "/home/user/"
extract_file_info "/var/log/"
extract_file_info "my file with spaces.txt"

# The function will print the file name and extension for each test case

Explanation of the Script

  1. Removing Trailing Slash: We first check if the path ends with a slash (/). If it does, we remove it using ${filepath%/} to ensure proper handling of directory paths.

  2. Extracting Base Name: Using basename -- "$filepath", we extract just the file or directory name from the full path.

  3. Handling Directories: We check if the base name contains a slash (/). If it does, this indicates that we're dealing with a directory path. In such cases, we simply output the base name as the file name and indicate that the extension is "(directory)".

  4. No Extension Case: If there are no dots in the base name ([[ "$base_name" != *.* ]]), we assume it has no extension.

  5. Extracting Extension: For files with extensions:

    • We use parameter expansion to split at the last dot and get the extension: extension="${base_name##*.}".
    • The file name is then everything before the last dot: file_name="${base_name%.*}".
  6. Output: Finally, we print the extracted file name and extension.

This script handles all the edge cases mentioned:

  • Absolute paths
  • Relative paths
  • Multiple dots in the file name
  • Files without an extension
  • Paths that are directories
  • Paths ending with a slash
  • Special characters or spaces in the path

You can run this script, and it will print the expected output for each test case.